package com.titaniume.java3;

import com.titaniume.java2.Employee;
import com.titaniume.java2.EmployeeData;
import org.junit.Test;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

/**
 *@program: JavaSenior
 *@description:
 *
 * Stream的终止操作
 *
 *@author: renfei.huang
 *@create: 2021-11-03 08:56
 */
public class StreamTest2 {

    //1-匹配与查找
    @Test
    public  void test1(){

        List<Employee> employees = EmployeeData.getEmployees();
//        allMatch(Predicate p) 检查是否匹配所有元素
        //练习：是否所有的员工的年龄都大于18
        boolean b = employees.stream().allMatch(e -> e.getAge() > 18);
        System.out.println(b);

//        anyMatch(Predicate p) 检查是否至少匹配一个元素
        //练习：是否存在员工的工资大于10000
        boolean b1 = employees.stream().anyMatch(e -> e.getSalary() > 10000);
        System.out.println(b1);

//        noneMatch(Predicate p) 检查是否没有匹配所有元素
        //练习： 是否存在员工姓“雷” 存在 false 不存在true
        boolean b3 = employees.stream().noneMatch(e -> e.getName().startsWith("雷"));
        System.out.println(b3);

//        findFirst() 返回第一个元素
        Optional<Employee> first = employees.stream().findFirst();
        System.out.println(first.get());

//        findAny() 返回当前流中的任意元素

        Optional<Employee> any = employees.stream().findAny();
        System.out.println(any.get());


    }


    @Test
    public  void test2(){
  //  count() 返回流中元素总数

        List<Employee> employees = EmployeeData.getEmployees();
        long count = employees.stream().filter(e -> e.getSalary() > 5000).count();
        System.out.println(count);

//        max(Comparator c) 返回流中最大值
        //练习：返回最高的工资
        Optional<Double> max = employees.stream().map(Employee::getSalary).max(Double::compare);
        System.out.println(max);


//        min(Comparator c) 返回流中最小值
        //练习：返回最高的工资最低的员工
        Optional<Employee> min = employees.stream()
                .min((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));
        System.out.println(min.get());

//        forEach(Consumer c) 内部迭代(使用 Collection 接口需要用户去做迭代， 称为外部迭代。相反，Stream API 使用内部迭 代——它帮你把迭代做了)
//      内部迭代
        employees.stream().forEach(System.out::println);
        //使用集合的遍历操作
        employees.forEach(System.out::println);

    }


    //2-归约
    @Test
    public  void  test3(){


//        reduce(T iden, BinaryOperator b) 可以将流中元素反复结合起来，得到一个值。返回 T
        //练习：计算1~10 自然数的和

        List<Integer> list =  Arrays.asList(1,2,3,4,5,6,7,8,9,10);

        //参数一：初始化值 0 BiFunction<T,T,T> 传入参数一 参数二 返回 参数三
        //Integer::sum  也是传递2个参数（方法引用）
        Integer sum = list.stream().reduce(10, Integer::sum);
        System.out.println(sum);


//        reduce(BinaryOperator b) 可以将流中元素反复结合起来，得到一个值。返回 Optional<T>

        //练习2： 计算公司中所有员工的工资总和

        List<Employee> employees = EmployeeData.getEmployees();
        Optional<Double> reduce = employees.stream().map(Employee::getSalary).reduce(Double::sum);
        System.out.println(reduce.get());


        Optional<Double> reduce1 = employees.stream().map(Employee::getSalary)
                .reduce((d1, d2) -> d1 + d2);
        System.out.println(reduce1.get());

    }


    //3-收集
    @Test
    public  void  test4(){


//        collect(Collector c) 将流转换为其他形式。接收一个 Collector 接口的实现，用于给Stream中元素做汇总 的方法
        //练习： 查找工资大于6000的员工，结果返回一个List或set

        List<Employee> employees = EmployeeData.getEmployees();
        List<Employee> employeeList = employees.stream().filter(e -> e.getSalary() > 6000).collect(Collectors.toList());
        employeeList.forEach(System.out::println);

        System.out.println("------------");

        Set<Employee> employees1 = employees.stream().filter(e -> e.getSalary() > 6000).collect(Collectors.toSet());
        employees1.forEach(System.out::println);


    }

}
